using System;
using System.Collections;
using System.Data;

using Castle.Facilities.NHibernateIntegration;
using Castle.Services.Transaction;

using NHibernate;
using BEGDC.CC.Entity;
using BEGDC.CC.BL.Common;
using BEGDC.CC.BL.Common.Query;
using BEGDC.Utility.Castle;
using BEGDC.Utility.ExceptionManagement;
using IQuery = BEGDC.CC.BL.Common.Query.IQuery;
using BEGDC.CC.BL.Workflow;
using System.Web;

namespace BEGDC.CC.BL.CCFlow.EV
{
    public class EVService : IEV
    {
        private EVFlow evFlow;
        public ISessionManager sessionManager;


        public EVService(ISessionManager sessionManager)
        {
            this.sessionManager = sessionManager;
            evFlow = new EVFlow();
        }

        #region ICCFlow Members

        public FlowBase GetFlowInstance
        {
            get
            {
                // TODO:  Add EVService.GetFlowInstance getter implementation
                return evFlow;
            }
        }

        #endregion

        #region IEV Members

        public void CopyEV(int appId)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {

                    IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as IQuery;
                    IEV evService = AppContainer.Instance[ServiceConst.EVService] as IEV;

                    #region Fetch and update obj info
                    //Get app
                    Application app = session.Get(typeof(Application), appId) as Application;
                    if (app == null)
                        throw new GDCException(ErrorCode.NoInstance_Exception, "No application with id : " + appId);

                    //Build new app
                    Application newapp = new Application();
                    newapp.RequesterNo = app.RequesterNo;
                    newapp.IsReviewedGuideline = app.IsReviewedGuideline;
                    newapp.ApplyForSomeoneElse = app.ApplyForSomeoneElse;
                    newapp.RequesterNameEN = HttpContext.Current.User.Identity.Name;
                    newapp.Account = app.Account;
                    newapp.RequesterDept = app.RequesterDept;
                    newapp.CATBranch = app.CATBranch;
                    newapp.DepartmentName = app.DepartmentName;
                    newapp.DepartmentType = app.DepartmentType;
                    newapp.ApplicationType = app.ApplicationType;
                    newapp.RequestedDateFrom = app.RequestedDateFrom;
                    newapp.AlternateDateFrom = app.AlternateDateFrom;
                    newapp.Activity = app.Activity;
                    newapp.AppNo = this.GenerateAppNo(newapp, false, false);

                    //Get CustInfo					
                    Entity.CustomerInfo custInfo = queryService.GetCustomerInfo(appId);
                    //Build new customer info
                    CustomerInfo newCustInfo = new CustomerInfo();
                    if (custInfo != null)
                    {
                        newCustInfo.Application = newapp;
                        newCustInfo.Company = custInfo.Company;
                        newCustInfo.Venue = custInfo.Venue;
                        newCustInfo.VisitObjective = custInfo.VisitObjective;
                    }

                    //Get Customer Attendee					
                    IList custAttList = session.Find("FROM CustomerAttendee WHERE CustomerInfoID = " + custInfo.Id);
                    //Build new CustomerAttendee
                    IList newCustAttList = new ArrayList();
                    if (custAttList != null && custAttList.Count > 0)
                    {
                        for (int i = 0; i < custAttList.Count; i++)
                        {
                            Entity.CustomerAttendee att = custAttList[i] as Entity.CustomerAttendee;
                            if (att != null)
                            {
                                CustomerAttendee newAttendee = new CustomerAttendee();
                                newAttendee.CustomerInfo = newCustInfo;
                                newAttendee.NameEN = att.NameEN;
                                newAttendee.Title = att.Title;
                                newAttendee.Company = att.Company;
                                newAttendee.NameCN = att.NameCN;
                                newAttendee.TitleEN = att.TitleEN;
                                newAttendee.CompanyEN = att.CompanyEN;
                                newAttendee.Responsibility = att.Responsibility;
                                newAttendee.Affects = att.Affects;
                                newAttendee.IsAttended = att.IsAttended;
                                newAttendee.IsExisted = att.IsExisted;
                                newAttendee.Remark = att.Remark;

                                newCustAttList.Add(newAttendee);
                            }
                        }
                    }

                    //Get AL Attendee list
                    IList alAttendee = session.Find("From ALAttendee WHERE AppID = " + appId);
                    //Build AL Attendee
                    IList newalAttendee = new ArrayList();
                    if (alAttendee != null && alAttendee.Count > 0)
                    {
                        for (int i = 0; i < alAttendee.Count; i++)
                        {
                            Entity.ALAttendee attendee = alAttendee[i] as Entity.ALAttendee;
                            if (attendee != null)
                            {
                                ALAttendee newAttendee = new ALAttendee();
                                newAttendee.Application = newapp;
                                newAttendee.EmployeeId = attendee.EmployeeId;
                                newAttendee.Title = attendee.Title;
                                newalAttendee.Add(newAttendee);
                            }
                        }
                    }

                    //Get Attachments					
                    IList attList = session.Find(" From Attachment WHERE AppID = " + appId);
                    //Build new Attachments
                    IList newAttList = new ArrayList();
                    if (attList != null && attList.Count > 0)
                    {
                        for (int i = 0; i < attList.Count; i++)
                        {
                            Entity.Attachment att = attList[i] as Attachment;
                            if (att != null)
                            {
                                Entity.Attachment newAtt = new Attachment();

                                newAtt.ActionPoint = att.ActionPoint;
                                newAtt.Application = newapp;
                                newAtt.AttachmentType = att.AttachmentType;
                                newAtt.Date = att.Date;
                                newAtt.FileName = att.FileName;
                                newAtt.FilePath = att.FilePath;
                                newAtt.Owner = att.Owner;

                                newAttList.Add(att);
                            }
                        }
                    }

                    #endregion

                    #region Save obj
                    //save application
                    session.Save(newapp);
                    //save customer info
                    session.Save(newCustInfo);

                    //save customer attendee
                    if (newCustAttList != null && newCustAttList.Count > 0)
                    {
                        for (int i = 0; i < newCustAttList.Count; i++)
                        {
                            session.Save(newCustAttList[i]);
                        }
                    }
                    //save AL attendee
                    if (newalAttendee != null && newalAttendee.Count > 0)
                    {
                        for (int i = 0; i < newalAttendee.Count; i++)
                        {
                            session.Save(newalAttendee[i]);
                        }
                    }
                    //save attachments
                    if (newAttList != null && newAttList.Count > 0)
                    {
                        for (int i = 0; i < newAttList.Count; i++)
                        {
                            session.Save(newAttList[i]);
                        }
                    }
                    #endregion

                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message);
                    throw new GDCException(ErrorCode.DB_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// Save a EV Request 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="log"></param>
        public void SaveEVRequest(Application app, CustomerInfo custInfo, IList attendeeList, IList custAttendeeList, ActionLog log)
        {
            try
            {
                using (ISession session = sessionManager.OpenSession())
                {
                    if (app == null)
                        throw new GDCException(ErrorCode.NoInstance_Exception, "object instance is null");

                    if (app.Id == 0)
                    {
                        app.AppNo = this.GenerateAppNo(app, false, false);
                        app.RequestDate = new Nullables.NullableDateTime(System.DateTime.Now);
                        UserManagement.IUser userService = AppContainer.Instance[ServiceConst.UserService] as UserManagement.IUser;
                        app.RequesterNo = userService.GetUserByEnglishName(app.RequesterNameEN);
                        //to save a flowInstance, need to save app first to offer flowInstance an appId
                        evFlow.SaveApplication(session, app);

                    }
                    else
                    {
                        evFlow.SaveApplication(session, app);
                    }

                    if (custInfo != null && custInfo.Id == 0)
                    {
                        evFlow.Save(session, custInfo);
                    }
                    else if (custInfo != null)
                    {
                        evFlow.Update(session, custInfo, custInfo.Id);
                    }

                    if (custAttendeeList != null && custAttendeeList.Count > 0)
                    {
                        session.Delete("FROM CustomerAttendee WHERE CustomerInfoId = " + custInfo.Id);
                        session.Flush();
                        for (int i = 0; i < custAttendeeList.Count; i++)
                        {
                            Entity.CustomerAttendee cust = custAttendeeList[i] as CustomerAttendee;
                            if (cust != null)
                            {
                                cust.CustomerInfo = custInfo;
                                session.Save(cust);
                            }
                        }
                    }

                    if (attendeeList != null && attendeeList.Count > 0)
                    {
                        session.Delete("From ALAttendee WHERE AppID = " + app.Id);
                        session.Flush();
                        for (int i = 0; i < attendeeList.Count; i++)
                        {
                            ALAttendee al = attendeeList[i] as ALAttendee;
                            if (al != null)
                            {
                                al.Application = app;
                                session.Save(al);
                            }
                        }
                    }
                    evFlow.SaveActionLog(session, log);
                }
            }
            catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
            {
                CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
            }
        }

        /// <summary>
        /// Start a new EV flow and drive the flow to COD Manager
        /// </summary>
        /// <param name="app"></param>
        /// <param name="log"></param>
        [Transaction(TransactionMode.Requires)]
        public void SubmitEVRequest(Application app, CustomerInfo custInfo, IList attendeeList, IList custAttendeeList, Employee applicant, Employee employee, int flowId, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    //
                    if ((app.AppNo != null) && (app.AppNo.IndexOf("-D") > 0))
                        app.AppNo = string.Empty;
                    app.AppNo = this.GenerateAppNo(app, true, true);
                    this.SaveEVRequest(app, custInfo, attendeeList, custAttendeeList, log);

                    if (flowId == 0)
                    {
                        //						if( evFlow.CheckWritableStep( session, app.Id, WorkTransition.EV_Request ))
                        //						{
                        //Start a flow
                        FlowInstance flowInstance = this.BuildFlowInstance(app, evFlow.Start(), WorkTransition.EV_Request, WorkTransition.EV_Request, SysDicItem.ProjectStatusFlag.QUERY);
                        evFlow.SaveFlowInstance(session, flowInstance);
                        //Init workflow members
                        evFlow.InitializeProjectMember(session, app.Id);
                    }


                    //app.DepartmentName.DepartmentType
                    string deptType = app.DepartmentType.DicItemKey;

                    #region update flowMember

                    //update applicant
                    FlowMember flMemberApplicant = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_Request, FlowTypes.EV);
                    flMemberApplicant.Employee = applicant;
                    session.Update(flMemberApplicant, flMemberApplicant.Id);
                    //update MeetingMinutes 
                    FlowMember flMemberMM = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_MeetingMinutes, FlowTypes.EV);
                    flMemberMM.Employee = applicant;
                    session.Update(flMemberMM, flMemberMM.Id);

                    //if approve person is request person, set approve person = request.ReportTo
                    if (applicant.Id.Equals(employee.Id) && applicant.ReportTo != null) employee = applicant.ReportTo;

                    if (deptType == "CAT")
                    {
                        //update catdirector approve app
                        FlowMember flMemberCAT = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_CATDirectorApprove, FlowTypes.EV);
                        flMemberCAT.Employee = employee;
                        session.Update(flMemberCAT, flMemberCAT.Id);
                        //update catdirector approve mm
                        FlowMember flMemberCATMM = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_CATApproveMM, FlowTypes.EV);
                        flMemberCATMM.Employee = employee;
                        session.Update(flMemberCATMM, flMemberCATMM.Id);

                    }
                    else
                    {
                        //update pso approve app
                        FlowMember flMemberPSO = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_PSOApprove, FlowTypes.EV);
                        flMemberPSO.Employee = employee;
                        session.Update(flMemberPSO, flMemberPSO.Id);
                        //update pso approve mm
                        FlowMember flMemberPSOMM = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_PSOApproveMM, FlowTypes.EV);
                        flMemberPSOMM.Employee = employee;
                        session.Update(flMemberPSOMM, flMemberPSOMM.Id);
                    }

                    #endregion

                    session.Flush();

                    evFlow.Perform(session, app, EVTransitionList.Submit);


                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdxEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdxEx.StackTrace, gdxEx.Message);
                    throw gdxEx;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        private string GetApplicantDeptType(ISession session, int appId)
        {
            string cmdText = " SELECT DicType.DicTypeKey AS DeptType ";
            cmdText += " FROM Application INNER JOIN DicItem ON DicItem.DicItemKey = Application.RequesterDept ";
            cmdText += " INNER JOIN DicType ON DicItem.DicTypeID = DicType.DicTypeID ";
            cmdText += " WHERE Application.AppID = " + appId;

            return BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, cmdText).Rows[0][0].ToString();
        }


        /// <summary>
        /// 		/// 
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        private string GenerateAppNo(Application app, bool isRequest, bool isApply)
        {
            int maxId;
            string year = string.Empty;
            if (app.AppNo == null)
                app.AppNo = string.Empty;
            if (app.AppNo != string.Empty)
            {
                string temp = app.AppNo;
                temp = temp.Replace("-D", string.Empty);
                BEGDC.CC.BL.Common.Query.IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;

                //if (isApply)
                //{
                //    maxId = queryService.GetMaxAppID(WorkflowTypes.EV, !isRequest);
                //    year = DateTime.Now.Year.ToString().Substring(2);
                //}
                //else
                //{
                //    year = temp.Substring(temp.Length - 7, 2);
                //    maxId = Convert.ToInt32(temp.Substring(temp.Length - 4));
                //}
                year = temp.Substring(temp.Length - 7, 2);
                maxId = Convert.ToInt32(temp.Substring(temp.Length - 4));
            }
            else
            {
                BEGDC.CC.BL.Common.Query.IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
                maxId = queryService.GetMaxAppID(WorkflowTypes.EV, !isRequest);
                year = DateTime.Now.Year.ToString().Substring(2);
            }

            string AppNo = "";
            if (app.DepartmentType != null)
            {
                if (app.DepartmentType.DicItemKey.Trim() == "CAT")
                {
                    AppNo += "HQ" + app.DepartmentName.DepartmentCode;
                }
                else
                {
                    AppNo += app.DepartmentName.DepartmentCode + app.Account;
                }
            }

            AppNo += "-";
            AppNo += year + "-" + maxId.ToString().PadLeft(4, '0');
            AppNo = "EV-" + AppNo;
            if ((!isRequest) && ((app.AppNo.IndexOf("-D") > 0) || (app.AppNo == string.Empty)))
                AppNo += "-D";
            return AppNo;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="appmemberTable"></param>
        /// <param name="log"></param>
        [Transaction(TransactionMode.Requires)]
        public void AssignEVRequest(Application app, Employee codStaff, CustomerInfo custInfo, IList attendeeList, IList custAttendeeList)
        {
            using (ISession session = sessionManager.OpenSession())
            {

                try
                {
                    this.SaveEVRequest(app, custInfo, attendeeList, custAttendeeList, null);

                    //check app codstaff
                    FlowMember codmember = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_Check, FlowTypes.EV);
                    codmember.Employee = codStaff;
                    session.Update(codmember, codmember.Id);

                    //check meeting minutes meeting minutes
                    FlowMember evmember = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_CODStaffCheckMM, FlowTypes.EV);
                    evmember.Employee = codStaff;
                    session.Update(evmember, evmember.Id);

                    //close flow
                    FlowMember closeMember = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_Close, FlowTypes.EV);
                    closeMember.Employee = codStaff;
                    session.Update(closeMember, closeMember.Id);

                    session.Flush();

                    evFlow.Perform(session, app, EVTransitionList.Assign);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message);
                    throw new GDCException(ErrorCode.EVService_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="appmemberTable"></param>
        /// <param name="log"></param>
        public void SaveAssignEVInfo(Hashtable appmemberTable, ActionLog log)
        {
        }

        [Transaction(TransactionMode.Requires)]
        public DataTable GetAllEVTasks()
        {
            // TODO:  Add EVService.GetAllEVTasks implementation
            return null;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="appID"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public IList GetEVMeetingByAppID(int appID)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    IList meetingList = session.Find("FROM EVMeeting WHERE AppID = " + appID);
                    return meetingList;
                }
                catch (NHibernate.HibernateException hex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(hex.StackTrace, hex.Message);
                    throw new GDCException(ErrorCode.DB_Exception, hex.Message, hex);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message);
                    throw new GDCException(ErrorCode.EVService_Exception, ex.Message, ex);
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="log"></param>
        [Transaction(TransactionMode.Requires)]
        public void SubmitCheckApp(Application app, CustomerInfo custInfo, IList list, IList custAttendeeList, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    //					if( evFlow.CheckWritableStep( session, app.Id, WorkTransition.EV_Check ))
                    //					{
                    app.AppNo = this.GenerateAppNo(app, true, false);
                    this.SaveEVRequest(app, custInfo, list, custAttendeeList, log);
                    evFlow.Perform(session, app, EVTransitionList.Check);
                    //					}
                    //					else
                    //					{
                    //						
                    //					}
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message);
                    throw new GDCException(ErrorCode.StepUnmap_Exceptin, "You cann't submit it for 2 times", gdcEx);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message);
                    throw new GDCException(ErrorCode.StepUnmap_Exceptin, "You cann't submit it for 2 times", ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="log"></param>
        [Transaction(TransactionMode.Requires)]
        public void SubmitAssignCheckApp(Application app, Employee emp)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    app.AppNo = this.GenerateAppNo(app, true, false);
                    evFlow.SaveApplication(session, app);

                    #region update flow member for meeting minutes check

                    FlowMember flMemberCheck = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_Check, FlowTypes.EV);
                    flMemberCheck.Employee = emp;
                    session.Update(flMemberCheck, flMemberCheck.Id);

                    FlowMember flMemberCheckMM = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_CODStaffCheckMM, FlowTypes.EV);
                    flMemberCheckMM.Employee = emp;
                    session.Update(flMemberCheckMM, flMemberCheckMM.Id);

                    FlowMember flMemberClose = evFlow.GetFlowMemberByAppStep(session, app.Id, WorkTransition.EV_Close, FlowTypes.EV);
                    flMemberClose.Employee = emp;
                    session.Update(flMemberClose, flMemberClose.Id);

                    session.Flush();
                    #endregion

                    evFlow.Perform(session, app, EVTransitionList.Check);
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void QueryCheckApp(Application app, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    evFlow.Query(session, app, "Request", "Normal", string.Empty);
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }

        }

        [Transaction(TransactionMode.Requires)]
        public void RejectCheckApp(Application app, string comment)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    evFlow.Perform(session, app, WorkTransition.Reject, comment);
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="log"></param>
        public void ApproveEVRequest(IList appList, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    foreach (Application app in appList)
                    {
                        //Drive the flow to next step
                        evFlow.Perform(session, app, EVTransitionList.Approve);
                    }
                    //Save operation log
                    evFlow.SaveActionLog(session, log);
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="evMeeting"></param>
        /// <param name="log"></param>
        public void SubmitMeetingMinutes(EVMeeting evMeeting, IList attendeeList, IList apListM, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    this.SaveMeetingMinutes(evMeeting, attendeeList, log);

                    #region Submit AP
                    //					if( apList != null && apList.Count > 0 )
                    //					{
                    //						ActionPoint ap = null;
                    //						for( int i=0; i<apList.Count; i++ )
                    //						{
                    //							ap = apList[i] as ActionPoint;
                    //							ap = session.Get(typeof(ActionPoint), ap.Id) as ActionPoint;
                    //							if( ap != null && ap.FlowID == 0 )
                    //							{
                    //								ap.FlowID = evFlow.StartAPFlow();
                    //								session.Update(ap, ap.Id);
                    //								evFlow.Perform(ap.FlowID, WorkTransition.Submit);
                    //								session.Flush();
                    //							}
                    //						}
                    //					}
                    #endregion

                    evFlow.Perform(session, evMeeting.Application, EVTransitionList.Submit);

                    //Start Action Point
                    IList apList = session.Find("FROM ActionPoint WHERE MeetingID = " + evMeeting.Id);
                    if (apList != null && apList.Count > 0)
                    {
                        ActionPoint ap = null;
                        for (int i = 0; i < apList.Count; i++)
                        {
                            ap = apList[i] as ActionPoint;
                            if (ap != null && ap.FlowID == 0)
                            {
                                ap.FlowID = evFlow.StartAPFlow();
                                session.Update(ap, ap.Id);

                                session.Flush();

                                evFlow.APPerform(ap.FlowID, WorkTransition.Submit);
                                session.Flush();
                            }
                        }
                    }
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="evMeeting"></param>
        /// <param name="attendeeList"></param>
        /// <param name="apList"></param>
        /// <param name="log"></param>
        public void CheckMeetingMinutes(EVMeeting evMeeting, IList attendeeList, IList apList, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    this.SaveMeetingMinutes(evMeeting, attendeeList, log);

                    #region Submit AP
                    //					if( apList != null && apList.Count > 0 )
                    //					{
                    //						ActionPoint ap = null;
                    //						for( int i=0; i<apList.Count; i++ )
                    //						{
                    //							ap = apList[i] as ActionPoint;
                    //							ap = session.Get(typeof(ActionPoint), ap.Id) as ActionPoint;
                    //							if( ap != null && ap.FlowID == 0 )
                    //							{
                    //								ap.FlowID = evFlow.StartAPFlow();
                    //								session.Update(ap, ap.Id);
                    //								evFlow.Perform(ap.FlowID, WorkTransition.Submit);
                    //								session.Flush();
                    //							}
                    //						}
                    //					}
                    #endregion

                    evFlow.Perform(session, evMeeting.Application, EVTransitionList.CheckMM);
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="evMeeting"></param>
        /// <param name="log"></param>
        public void ApproveMeetingMinutes(EVMeeting evMeeting, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    evFlow.Perform(session, evMeeting.Application, EVTransitionList.Approve);

                    IList apList = session.Find("FROM ActionPoint WHERE MeetingID = " + evMeeting.Id);
                    if (apList != null && apList.Count > 0)
                    {
                        ActionPoint ap = null;
                        for (int i = 0; i < apList.Count; i++)
                        {
                            ap = apList[i] as ActionPoint;
                            if (ap != null && ap.FlowID == 0)
                            {
                                ap.FlowID = evFlow.StartAPFlow();
                                session.Update(ap, ap.Id);

                                session.Flush();

                                evFlow.APPerform(ap.FlowID, WorkTransition.Submit);
                                session.Flush();
                            }
                        }
                    }

                    evFlow.SaveActionLog(session, log);
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="log"></param>
        public void Drawback(Application app, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    //
                    evFlow.Drawback(session, app);
                    //
                    evFlow.SaveActionLog(session, log);
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="flowId"></param>
        /// <param name="comment"></param>
        public void Drawback(long flowId, string comment)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    #region drawback ap if drawback approve mm
                    IList flowList = session.Find("From FlowInstance Where FlowID = " + flowId);
                    if (flowList != null && flowList.Count > 0)
                    {
                        FlowInstance instance = flowList[0] as FlowInstance;
                        if (instance != null)
                        {
                            if (instance.CurrentStep.StepCode == WorkTransition.EV_Close)
                            {
                                IList meetings = session.Find("From EVMeeting Where AppID = " + instance.Application.Id);
                                EVMeeting meeting = meetings[0] as EVMeeting;
                                IList apList = session.Find("From ActionPoint Where MeetingID = " + meeting.Id);
                                if (apList != null && apList.Count > 0)
                                {
                                    for (int i = 0; i < apList.Count; i++)
                                    {
                                        ActionPoint ap = apList[i] as ActionPoint;
                                        ap.FlowID = 0;
                                        session.Update(ap, ap.Id);
                                    }
                                }
                            }
                        }
                    }
                    #endregion

                    this.GetFlowInstance.Drawback(session, flowId, comment);

                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="flowID"></param>
        /// <param name="activeStep"></param>
        public void Query(long flowID, string activeStep, string comment)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    evFlow.Query(session, flowID, activeStep, SysDicItem.ProjectStatusFlag.QUERY, comment);
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="flowID"></param>
        public void ReplyQuery(long flowID, string comemnt)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.ReplyInquiry(session, flowID, comemnt);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="evMeeting"></param>
        /// <param name="log"></param>
        public void SaveMeetingMinutes(EVMeeting evMeeting, IList meetingAttendees, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {

                    //Save a meeting minutes
                    if (evMeeting.Id == 0)
                    {
                        evFlow.Save(session, evMeeting);
                    }
                    else
                    {
                        evFlow.Update(session, evMeeting, evMeeting.Id);
                    }

                    session.Delete("FROM EVMeetingAttendee WHERE MeetingID = " + evMeeting.Id);

                    session.Flush();

                    if (meetingAttendees != null && meetingAttendees.Count > 0)
                    {
                        for (int i = 0; i < meetingAttendees.Count; i++)
                        {
                            EVMeetingAttendee attendee = meetingAttendees[i] as EVMeetingAttendee;
                            if (attendee != null)
                            {
                                session.Save(attendee);
                            }
                        }
                    }
                    //Save action log
                    evFlow.SaveActionLog(session, log);


                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="employee"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public DataTable GetEVTasksByEmployee(BEGDC.CC.Entity.Employee employee)
        {
            try
            {
                IQuery queryService = new QueryService(this.sessionManager);
                return queryService.QueryTaskList(employee.Id, employee.Id, BEGDC.CC.BL.Workflow.WorkflowTypes.EV);
            }
            catch (GDCException gdcex)
            {
                CCS.Utility.LogAccess.WriteErrLog(gdcex.StackTrace, gdcex.Message); throw gdcex;
            }
            catch (Exception)
            {
                throw new GDCException(BEGDC.CC.BL.Common.ErrorCode.QueryService_Exception, "Query EV tasks error!");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="flowId"></param>
        /// <param name="currentStep"></param>
        /// <param name="currentActiveStep"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        private FlowInstance BuildFlowInstance(Application app, long flowId, string currentStep, string currentActiveStep, string state)
        {
            try
            {
                FlowInstance flowInstance = new FlowInstance();
                flowInstance.Application = app;

                IUtility utiService = AppContainer.Instance[ServiceConst.UtilityService] as IUtility;
                flowInstance.FlowID = flowId;
                flowInstance.State = utiService.QueryStateByCode(state);
                int typeId = utiService.GetDicItemID(WorkflowTypes.CV, BEGDC.CC.BL.Common.DicType.Application_Type);
                flowInstance.CurrentStep = utiService.QueryStepByCode(currentStep, typeId);
                flowInstance.CurrentActiveStep = utiService.QueryStepByCode(currentActiveStep, typeId);

                return flowInstance;
            }
            catch (Exception ex)
            {
                CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        [Transaction(TransactionMode.Requires)]
        public void CloseEV(Application app)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    evFlow.SaveApplication(session, app);
                    evFlow.Perform(session, app, EVTransitionList.Close);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
            }
        }

        #endregion

        #region Save, Update and Get Meeting&Attendee
        /// <summary>
        /// 
        /// </summary>
        /// <param name="attendee"></param>
        /// <param name="log"></param>
        [Transaction(TransactionMode.Requires)]
        public void SaveAttendee(EVMeetingAttendee attendee, ActionLog log)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    if (attendee == null)
                        throw new GDCException(ErrorCode.Null_Exception, "object is null");
                    if (attendee.Id == 0)
                    {
                        evFlow.Save(session, attendee);
                    }
                    else
                    {
                        evFlow.Update(session, attendee, attendee.Id);
                    }

                    evFlow.SaveActionLog(session, log);
                }
                catch (GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="attendee"></param>
        /// <param name="log"></param>
        [Transaction(TransactionMode.Requires)]
        public void UpdateAttendee(EVMeetingAttendee attendee, ActionLog log)
        {

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="attendeeID"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public EVMeetingAttendee GetAttendeeByID(int attendeeID)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    EVMeetingAttendee attendee = session.Get(typeof(EVMeetingAttendee), attendeeID, NHibernate.LockMode.Read) as EVMeetingAttendee;
                    return attendee;
                }
                catch (HibernateException hex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(hex.StackTrace, hex.Message);
                    throw new GDCException(ErrorCode.DB_Exception, hex.Message, hex);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message);
                    throw new GDCException(ErrorCode.EVService_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="meetingID"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public EVMeeting GetEVMeetingByID(int meetingID)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    return session.Get(typeof(EVMeeting), meetingID) as EVMeeting;
                }
                catch (HibernateException hex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(hex.StackTrace, hex.Message);
                    throw new GDCException(ErrorCode.DB_Exception, hex.Message, hex);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message);
                    throw new GDCException(ErrorCode.EVService_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }
        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="appId"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public string GenerateAPNo(int meetingID)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                Entity.EVMeeting meeting = session.Get(typeof(EVMeeting), meetingID) as EVMeeting;
                if (meeting != null)
                {
                    /*
                    string cmdText = "SELECT Department.DepartmentCode as Dept, Description, Account, Others FROM Application INNER JOIN Department ON DepartmentName = Department.DepartmentID WHERE AppID = " + meeting.Application.Id;
                    DataTable appTable = BEGDC.Utility.NHibernate.NHibernateUtil.Execute( session, cmdText );
					
                    string dept = "";

					
                    if( appTable != null && appTable.Rows.Count > 0 )
                    {
                        DataRow row = appTable.Rows[0];
                        if( row["Dept"].ToString() != "N/A")
                        {
                            dept = row["Dept"].ToString();
//							dept = ((DicItem)(session.Find("FROM DicItem WHERE DicItemKey = '" + dept + "'" )[0])).Description;
                        }
                        else if( row["Account"].ToString() != "N/A" )
                        {
                            dept = row["Account"].ToString();
                            dept = ((DicItem)(session.Find("FROM DicItem WHERE DicItemKey = '" + dept + "'" )[0])).Description;
                        }
                        else
                        {
                            dept = row["Others"].ToString();
                        }
                    }
                    */
                    string dept = "";
                    if (meeting.Application.DepartmentType != null)
                    {
                        if (meeting.Application.DepartmentType.DicItemKey.Trim() == "CAT")
                        {
                            dept += "HQ" + meeting.Application.DepartmentName.DepartmentCode;
                        }
                        else
                        {
                            dept += meeting.Application.DepartmentName.DepartmentCode + meeting.Application.Account;
                        }
                    }

                    string MaxID = "0";
                    string queryText = "SELECT Max(APID) FROM ActionPoint";
                    DataTable table = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, queryText);
                    if (table != null && table.Rows.Count > 0)
                    {
                        if (table.Rows[0][0] != System.DBNull.Value)
                            MaxID = table.Rows[0][0].ToString();
                        else
                            MaxID = "0";
                    }

                    int newID = Convert.ToInt32(MaxID) + 1;
                    if (newID > 9999) newID = newID % 1000;

                    string apNo = "EVAP-" + dept + DateTime.Now.ToString("yyyyMMdd") + "-" + newID.ToString().PadLeft(3, '0');

                    return apNo;
                }
                else
                {
                    return null;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="apId"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public ActionPoint GetAPByID(int apId)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    return session.Get(typeof(ActionPoint), apId) as ActionPoint;
                }
                catch (HibernateException hex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(hex.StackTrace, hex.Message);
                    throw new GDCException(ErrorCode.DB_Exception, hex.Message, hex);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message);
                    throw new GDCException(ErrorCode.EVService_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// UpdateCloseDate
        /// </summary>
        /// <param name="apId"></param>
        /// <param name="closedDate"></param>
        /// <param name="dueDate"></param>
        [Transaction(TransactionMode.Requires)]
        public void UpdateCloseDate(int apId, Nullables.NullableDateTime closedDate, Nullables.NullableDateTime dueDate)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    ActionPoint ap = session.Get(typeof(ActionPoint), apId) as ActionPoint;
                    if (ap != null)
                    {
                        ap.ClosedDate = closedDate;
                        ap.DueTime = dueDate;
                        session.Update(ap);
                        session.Flush();
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ap"></param>
        [Transaction(TransactionMode.Requires)]
        public void SaveAPRequest(ActionPoint ap, IList partnerList)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    if (ap.Id > 0)
                    {
                        session.Update(ap, ap.Id);
                        if (partnerList != null && partnerList.Count > 0)
                            session.Delete("FROM APPartner WHERE APID = " + ap.Id);
                    }
                    else
                    {
                        //ap.FlowID = evFlow.StartAPFlow();
                        session.Save(ap);
                    }
                    session.Flush();
                    if (partnerList != null && partnerList.Count > 0)
                    {
                        for (int i = 0; i < partnerList.Count; i++)
                        {
                            APPartner partner = (APPartner)partnerList[i];
                            partner.ActionPoint = ap;
                            session.Save(partner);
                        }
                        session.Flush();
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ap"></param>
        [Transaction(TransactionMode.Requires)]
        public void SubmitAPRequest(ActionPoint ap, IList partnerList)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    if (ap.FlowID == 0)
                    {
                        ap.FlowID = evFlow.StartAPFlow();
                    }
                    //Close AP if submit the ap in last step  ** add by John
                    if (ap.FlowID != 0)
                    {
                        string sql = "Select APID From vw_APInfo Where APStep ='EndAP' And Status='Open' And APID=" + ap.Id.ToString();
                        DataTable table = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, sql);
                        if (table.Rows.Count != 0)
                        {
                            ap.Status = "Close";
                            //Update By John User manually update closed date
                            //ap.ClosedDate = new Nullables.NullableDateTime(System.DateTime.Now);
                        }
                    }
                    this.SaveAPRequest(ap, partnerList);
                    this.evFlow.APPerform(ap.FlowID, WorkTransition.Submit);

                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ap"></param>
        /// <param name="partnerList"></param>
        [Transaction(TransactionMode.Requires)]
        public void RejectAP2Owner(ActionPoint ap, IList partnerList)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    this.SaveAPRequest(ap, partnerList);
                    this.evFlow.APPerform(ap.FlowID, WorkTransition.Reject);

                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="nameEN"></param>
        /// <param name="meetingid"></param>
        /// <returns></returns>
        public bool IsCodStaffForAP(string nameEN, int meetingid)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    EVMeeting meeting = session.Get(typeof(Entity.EVMeeting), meetingid) as EVMeeting;
                    if (meeting != null)
                    {
                        Employee codStaff = evFlow.GetFlowMemberByAppStep(session, meeting.Application.Id, WorkTransition.EV_Check, FlowTypes.EV).Employee;
                        if (codStaff.NameEN.TrimEnd() == nameEN)
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        throw new GDCException(ErrorCode.Other_Exception, "No Meeting with AP existed");
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message);
                    throw new GDCException(ErrorCode.Other_Exception, ex.Message, ex);
                }

            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="APID"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public DataTable GetAPInfo(int APID)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    string cmdText = "SELECT * FROM vw_APInfo WHERE APID = " + APID;
                    return BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, cmdText);
                }
                catch (HibernateException hex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(hex.StackTrace, hex.Message); throw new GDCException(ErrorCode.DB_Exception, hex.Message, hex);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.EVService_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="APID"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public DataTable GetAPCommentsHistory(int APID)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    string cmdText = "SELECT * FROM APComments WHERE APID = " + APID;
                    return BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, cmdText);
                }
                catch (HibernateException hex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(hex.StackTrace, hex.Message); throw new GDCException(ErrorCode.DB_Exception, hex.Message, hex);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.EVService_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="APID"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public int GetMaxAPCommentID(int APID)
        {
            if (APID == 0)
                return 0;
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    string cmdText = "SELECT Max(APNo) FROM APComments WHERE APID = " + APID;
                    DataTable table = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, cmdText);
                    if (table != null && table.Rows.Count > 0)
                        if (table.Rows[0][0] != System.DBNull.Value)
                            return (int)table.Rows[0][0];
                        else
                            return 0;

                    else
                        return 0;
                }
                catch (HibernateException hex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(hex.StackTrace, hex.Message); throw new GDCException(ErrorCode.DB_Exception, hex.Message, hex);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.EVService_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// delete an AP record by it's ID
        /// </summary>
        /// <param name="apId"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public void DeleteAP(int apId)
        {
            if (apId > 0)
            {
                using (ISession session = sessionManager.OpenSession())
                {
                    try
                    {
                        session.Delete("FROM ActionPoint WHERE APID = " + apId);
                        session.Flush();
                    }
                    catch (HibernateException ex)
                    {
                        CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                    }
                    catch
                    {
                    }
                    finally
                    {
                        session.Close();
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="comment"></param>
        [Transaction(TransactionMode.Requires)]
        public void SubmitAPComment(APComment comment)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    session.Save(comment);
                }
                catch (HibernateException hex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(hex.StackTrace, hex.Message); throw new GDCException(ErrorCode.DB_Exception, hex.Message, hex);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.EVService_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void Archive(long flowID)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Archive(session, flowID);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void Resume(long flowID, string comment)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Resume(session, flowID, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void Suspend(long flowID, string comment)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Suspend(session, flowID, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void Callback(long flowID, string comment)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Callback(session, flowID, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void Cancel(long flowID, string comment)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Cancel(session, flowID, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="table"></param>
        [Transaction(TransactionMode.Requires)]
        public void BatchApprove(string flowIds)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    string[] flowIdArray = flowIds.Split(';');

                    for (int i = 0; i < flowIdArray.Length; i++)
                    {
                        long flowId = Convert.ToInt64(flowIdArray[i]);
                        //						FlowInstance fl = session.Get(typeof(FlowInstance), flowId) as FlowInstance;
                        evFlow.Perform(session, Convert.ToInt64(flowId), EVTransitionList.Approve, string.Empty);
                    }

                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.EVService_Exception, "Batch Approve Failed" + ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="stepName"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Requires)]
        public bool IsCurrentStep(int appId, string stepName)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                string cmdText = "SELECT Step.StepCode FROM Application INNER JOIN FlowInstance ON Application.AppID = FlowInstance.AppID INNER JOIN ";
                cmdText += " Step ON FlowInstance.CurrentActiveStep = Step.StepID WHERE Application.AppID = " + appId;

                try
                {
                    DataTable table = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, cmdText);
                    if (table != null && table.Rows.Count > 0)
                    {
                        if (stepName == table.Rows[0][0].ToString())
                        {
                            return true;
                        }
                        else
                            return false;
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.DB_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void ReAssign(long flowID, string employee)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                FlowInstance instance = this.GetFlowInstance.QueryFlowInstance(session, flowID);

                FlowMember member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.EV_Check, FlowTypes.EV);
                // add by FanYe
                if (member.Employee != null)
                {
                    if (member.Employee.Id == instance.CurrentActiveOwner)
                        instance.CurrentActiveOwner = employee;
                    if (member.Employee.Id == instance.CurrentOwner)
                        instance.CurrentOwner = employee;
                    session.Update(instance, instance.Id);
                }

                member.Employee = new Employee();
                member.Employee.Id = employee;
                session.Update(member, member.Id);

                member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.EV_CODStaffCheckMM, FlowTypes.EV);
                member.Employee = new Employee();
                member.Employee.Id = employee;
                session.Update(member, member.Id);

                member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.EV_Close, FlowTypes.EV);
                member.Employee = new Employee();
                member.Employee.Id = employee;
                session.Update(member, member.Id);

                session.Flush();
                this.GetFlowInstance.SaveActionLog(session, instance.Application.Id, BEGDC.CC.BL.Workflow.Action.Reassign, instance.CurrentStep.StepCode, instance.CurrentStep.StepCode, string.Empty);
            }
        }


        #region Action Point
        /// <summary>
        /// Action Point
        /// </summary>
        [Transaction(TransactionMode.Requires)]
        public bool IsAutomaticCloseAP(ActionPoint ap)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    string cmdText = "SELECT Distinct Employee.NameEN FROM Employee INNER JOIN APPartner AS p  ON Employee.EmployeeNo = p.EmployeeNo INNER JOIN Department ON Employee.Department = Department.DepartmentID INNER JOIN DicItem ON p.PartnerType = DicItem.DicItemID ";
                    cmdText += " WHERE APID = " + ap.Id;
                    cmdText += " and Employee.NameEN not in (select Distinct AnsweredBy FROM APComments WHERE APID = '" + ap.Id + "')";

                    DataTable table = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, cmdText);

                    if (table == null && table.Rows.Count <= 0) return false;

                    //string ownerAndContributerSQL = "SELECT Distinct Employee.NameEN FROM Employee INNER JOIN APPartner AS p  ON Employee.EmployeeNo = p.EmployeeNo INNER JOIN Department ON Employee.Department = Department.DepartmentID INNER JOIN DicItem ON p.PartnerType = DicItem.DicItemID ";
                    //ownerAndContributerSQL += "WHERE APID = " + ap.Id;

                    //DataTable ownerAndContributerTable = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, ownerAndContributerSQL);

                    //if (ownerAndContributerTable != null && ownerAndContributerTable.Rows.Count > 0)
                    //{
                    //    foreach (DataRow row in ownerAndContributerTable.Rows)
                    //    {
                    //        string answeredBySearchSQL = "SELECT * FROM APComments WHERE APID = '" + ap.Id + "' and AnsweredBy ='" + row[0] + "'";
                    //        DataTable answeredBySearchTable = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, answeredBySearchSQL);

                    //        if (answeredBySearchTable == null || answeredBySearchTable.Rows.Count <= 0) return false;
                    //    }
                    //}
                    return true;
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.DB_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }
        #endregion

        /// <summary>
        /// One Action Point
        /// </summary>
        //[Transaction(TransactionMode.Requires)]
        //public DataTable GetDoNotSubmitAPCommentPersons(ActionPoint ap)
        //{
        //    using (ISession session = sessionManager.OpenSession())
        //    {
        //        try
        //        {
        //            string cmdText = "SELECT Distinct p.EmployeeNo, Employee.NameEN FROM Employee INNER JOIN APPartner AS p  ON Employee.EmployeeNo = p.EmployeeNo INNER JOIN Department ON Employee.Department = Department.DepartmentID INNER JOIN DicItem ON p.PartnerType = DicItem.DicItemID ";
        //            cmdText += " WHERE APID = " + ap.Id;
        //            cmdText += " and Employee.NameEN not in (select Distinct AnsweredBy FROM APComments WHERE APID = '" + ap.Id + "')";

        //            DataTable table = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, cmdText);
        //            return table;
        //        }
        //        catch (Exception ex)
        //        {
        //            CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.DB_Exception, ex.Message, ex);
        //        }
        //        finally
        //        {
        //            session.Close();
        //        }
        //    }
        //}

        #region Unclosed ActionPoint
        /// <summary>
        /// Unclosed Action Point List
        /// </summary>
        public IList GetUnClosedAP()
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    IList unClosedAPList = session.Find("from ActionPoint as ap where ap.Status <> 'Close' and DueTime < CONVERT(varchar(10),GETDATE(),120)");
                    return unClosedAPList;
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.DB_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }
        #endregion

        #region Persons' Emails
        /// <summary>
        /// Get Email String
        /// </summary>
        public string GetEmailsOfUnClosedAPoint(ActionPoint ap)
        {

            string toEmailStr = string.Empty;
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    if (ap == null) return toEmailStr;
                    //Get Email String 
                    string cmdText = "select emp.Email from Employee as emp inner join ";
                    cmdText += "(SELECT Distinct p.EmployeeNo, Employee.NameEN FROM Employee INNER JOIN APPartner AS p  ON Employee.EmployeeNo = p.EmployeeNo INNER JOIN Department ON Employee.Department = Department.DepartmentID INNER JOIN DicItem ON p.PartnerType = DicItem.DicItemID ";
                    cmdText += " WHERE APID = '" + ap.Id + "' and Employee.NameEN not in (select Distinct AnsweredBy FROM APComments WHERE APID = '" + ap.Id + "')) as tab on tab.EmployeeNo = emp.EmployeeNo";

                    DataTable table = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, cmdText);
                    if (table != null && table.Rows.Count > 0)
                    {
                        foreach (DataRow row in table.Rows)
                        {
                            toEmailStr += string.IsNullOrEmpty(row[0].ToString()) ? string.Empty : row[0].ToString() + ";";
                        }
                    }


                    return toEmailStr;
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw new GDCException(ErrorCode.DB_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }
        #endregion


        /// <summary>
        /// Start Action Point
        /// </summary>
        /// <param name="session">Session</param>
        /// <param name="evMeeting">EV Meeting</param>
        [Transaction(TransactionMode.Requires)]
        public void StartActionPoint(EVMeeting evMeeting)
        {
            using (ISession session = sessionManager.OpenSession())
            {
                try
                {
                    IList apList = session.Find("FROM ActionPoint WHERE MeetingID = " + evMeeting.Id);
                    if (apList != null && apList.Count > 0)
                    {
                        ActionPoint ap = null;
                        for (int i = 0; i < apList.Count; i++)
                        {
                            ap = apList[i] as ActionPoint;
                            if (ap != null && ap.FlowID == 0)
                            {
                                ap.FlowID = evFlow.StartAPFlow();
                                session.Update(ap, ap.Id);
                                session.Flush();
                                evFlow.APPerform(ap.FlowID, WorkTransition.Submit);
                                session.Flush();
                            }
                        }
                    }
                }
                catch (BEGDC.Utility.ExceptionManagement.GDCException gdcEx)
                {
                    CCS.Utility.LogAccess.WriteErrLog(gdcEx.StackTrace, gdcEx.Message); throw gdcEx;
                }
                finally
                {
                    session.Close();
                }
            }
        }
    }
}
